﻿using Common.Logging;
using Quartz;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wicresoft.EKA.NRemedy;
using Oracle.DataAccess.Client;
using System.Text.RegularExpressions;

namespace Wicresoft.EKA.ITSM.WindowsService
{

    public class ConnectionInfo
    {
        public string SQL { get; set; }
        public OracleConnection Connection { get; set; }
    }


    /// <summary>
    /// A sample remedy job 
    /// </summary>
    public class SMSJob : IJob
    {
        private static readonly ILog logger = LogManager.GetCurrentClassLogger();
        private static readonly string ARServer = ConfigurationManager.AppSettings["ARServer"];
        private static readonly string AdminName = ConfigurationManager.AppSettings["AdminName"];
        private static readonly string AdminPassword = ConfigurationManager.AppSettings["AdminPassword"];
        private Dictionary<string, ConnectionInfo> connes = new Dictionary<string, ConnectionInfo>();
        private List<string> errorCon = new List<string>();

        /// <summary>
        /// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
        /// fires that is associated with the <see cref="IJob" />.
        /// </summary>
        /// <remarks>
        /// The implementation may wish to set a  result object on the 
        /// JobExecutionContext before this method exits.  The result itself
        /// is meaningless to Quartz, but may be informative to 
        /// <see cref="IJobListener" />s or 
        /// <see cref="ITriggerListener" />s that are watching the job's 
        /// execution.
        /// </remarks>
        /// <param name="context">The execution context.</param>
        public void Execute(IJobExecutionContext context)
        {

            logger.Info("SMSJob running...");

            try
            {
                using (var arContext = new ARLoginContext(ARServer, AdminName, AdminPassword))
                {

                    ARProxy<WS_MessageModel> ar = new ARProxy<WS_MessageModel>(arContext);

                    var list = ar.GetListEntry("'cInt_Status'=0", new List<uint>()  
{  
WS_MessageModel.RequestID_ID,
WS_MessageModel.cChr_PhoneNumber_ID,
WS_MessageModel.cChr_Message_ID,
WS_MessageModel.cChr_Others3_ID,
});

                    ConnectionInfo con;
                    foreach (var item in list)
                    {
                        try
                        {
                            if (!IsMobilePhone(item.cChr_PhoneNumber))
                            {
                                item.cInt_Status = 4;
                                ar.SetEntry(item);
                                continue;
                            }

                            con = GetCon(item.cChr_Others3);
                            if (con == null)
                            {
                                item.cInt_Status = 3;
                                item.cChr_Others1 = "数据库错误，请检查数据库连接配置及SQL";
                                ar.SetEntry(item);
                                continue;
                            }

                            InsertSMS(con.Connection, con.SQL, item.cChr_PhoneNumber, item.cChr_Message);
                            item.cInt_Status = 1;
                            ar.SetEntry(item);
                        }
                        catch (Exception e)
                        {
                            item.cInt_Status = 2;
                            item.cChr_Others1 = e.Message;
                            ar.SetEntry(item);

                            logger.Error(" RequestID:" + item.RequestID, e);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e);
            }


            foreach (var item in connes.Values)
            {
                item.Connection.Close();
            }

            logger.Info("SMSJob run finished.");
        }

        public static bool IsMobilePhone(string input)
        {
            Regex regex = new Regex("^1\\d{10}$");
            return regex.IsMatch(input);
        }

        public ConnectionInfo GetCon(string name)
        {

            if (connes.ContainsKey(name)) return connes[name];
            if (errorCon.Contains(name)) return null;

            var conStr = ConfigurationManager.AppSettings["SMSDB_" + name];

            if (string.IsNullOrWhiteSpace(conStr))
            {
                logger.Error(name + "   需要配置数据库连接");
                errorCon.Add(name);
                return null;
            }

            var conSQL = ConfigurationManager.AppSettings["SMSSQL_" + name];

            if (string.IsNullOrWhiteSpace(conSQL))
            {
                logger.Error(name + "   需要配置SQL 语句");
                errorCon.Add(name);
                return null;
            }

            OracleConnection con = new OracleConnection(conStr);
            try
            {
                con.Open();
            }
            catch (Exception e)
            {
                logger.Error(name + "   数据库连接打开错误");
                errorCon.Add(name);
                return null;
            }

            var info = new ConnectionInfo()
                {
                    Connection = con,
                    SQL = conSQL
                };

            connes[name] = info;
            return info;
        }


        public int InsertSMS(OracleConnection con, string sql, string num, string msg)
        {
            var command = con.CreateCommand();

            command.Connection = con;
            command.CommandText = sql;
            command.CommandType = System.Data.CommandType.Text;
            command.BindByName = true;

            command.Parameters.Add(new OracleParameter()
            {
                ParameterName = "PhoneNumber",
                Value = num,
            });

            command.Parameters.Add(new OracleParameter()
            {
                ParameterName = "Message",
                Value = msg,
            });

            return command.ExecuteNonQuery();

        }


    }
}
